<?
require_once("class_GenericMultiComposit.php");
require_once("class_GenericSerialComposit.php");
require_once("class_IndexName.php");
require_once("class_TableToastName.php");

/********************************************************************************************************/
/* This class represents one row from any table which hase non composit not autoincremented PRIMARY KEY */
/********************************************************************************************************/

class TableName extends GenericMultiComposit {
    private $toast;

    public function TableName($in_id=false) {
	parent::__construct('table_name','id',$in_id);
	$this->add_composit('index_name','IndexName','tn_id','id');

	if ($in_id) {
	    $this->sql->select_c("SELECT 1 FROM table_toast_name WHERE tn_id=".$in_id);
	    if ($this->sql->get_num_rows() > 0) {
		$this->toast=new TableToastName($in_id);
	    } else {
		$this->toast=false;
	    }
	}
    }

    public function add_toast($t_relid,$prod_sql) {
	$prod_sql->select_c("SELECT t.oid AS t_relid,t.relname AS t_relname,t.reltoastidxid AS t_i_relid,i.relname AS t_i_relname
    FROM pg_class t
    INNER JOIN pg_class i ON t.reltoastidxid=i.oid
    WHERE t.oid=".$t_relid);
//	$toast_res=$prod_sql->get_row_hash();
	$this->_create_toast($prod_sql->get_row_hash());
    }

    public function discover_toast($prod_sql) {
	$prod_sql->select_c("SELECT t.oid AS t_relid,t.relname AS t_relname,t.reltoastidxid AS t_i_relid,i.relname AS t_i_relname
    FROM pg_class t
    INNER JOIN pg_class r ON r.reltoastrelid=t.oid
    INNER JOIN pg_class i ON t.reltoastidxid=i.oid
    WHERE r.oid=".$this->get_field('obj_oid'));

	if ($prod_sql->get_num_rows() == 1) {
	    if (!$this->toast) {
		$this->_create_toast($prod_sql->get_row_hash());
	    }
	} else {
	    if ($this->toast) {
		$this->toast->set_field('alive','f');
		$this->toast->save();
		$this->toast=false;
	    }
	}
    }



    public function discover_indexes($prod_sql) {
	$idx_stat_dicover_condition=array('alive'=>'t');
	$this->initiate_composit('index_name',$idx_stat_dicover_condition);
	$exist_ids=$this->get_composit('index_name',COLLECTION_ID_ARRAY);

	$prod_sql->select_c("SELECT i.indexrelid,c.relname,i.indisunique,i.indisprimary
	FROM pg_index i
	JOIN pg_class c ON i.indexrelid=c.oid
	WHERE i.indrelid=".$this->get_field('obj_oid'));
	
	foreach ($prod_sql->get_result() as $prod_idx) {
	    $exist_id=$this->composit_obj_exists('index_name','obj_oid',$prod_idx['indexrelid']);
	    if (!$exist_id) {
		$in=new IndexName;
		$in->set_field('tn_id',$this->id);
		$in->set_field('obj_oid',$prod_idx['indexrelid']);
		$in->set_field('is_unique',$prod_idx['indisunique']);
		$in->set_field('is_primary',$prod_idx['indisprimary']);
		$in->set_field('idx_name',$prod_idx['relname']);
		$in->save();
		$this->add_composit_object('index_name',$in->get_id());
	    } else {
		foreach ($exist_ids as $id=>$val) {
		    if ($val==$exist_id) {
			unset($exist_ids[$id]);
		    }
		}
	    }
	}
	foreach ($exist_ids as $old_id) {
	    $old_idx=new IndexName($old_id);
	    $old_idx->set_field('alive','f');
	    $old_idx->save();
	    $this->remove_composit_object('index_name',$old_id);
	}
    }

    private function _create_toast($array) {
	$this->toast=new TableToastName;
	$this->toast->set_field('tn_id',$this->id);
	$this->toast->set_field('obj_oid',$array['t_relid']);
	$this->toast->set_field('tbl_name',$array['t_relname']);
	$this->toast->save();

	$this->toast->create_index($array['t_i_relid'],$array['t_i_relname']);
    }

    public function get_stat($time_id,$prod_sql) {
	$va_stat_q="SELECT
pg_stat_get_last_vacuum_time(oid) AS last_vacuum,
pg_stat_get_last_autovacuum_time(oid) AS last_autovacuum,
pg_stat_get_last_analyze_time(oid) AS last_analyze,
pg_stat_get_last_autoanalyze_time(oid) AS last_autoanalyze
FROM pg_class WHERE oid=".$this->get_field('obj_oid');
	$prod_sql->select_c($va_stat_q);
	$va_stat=$prod_sql->get_row_hash();
	$lv=(isset($va_stat['last_vacuum']) ? "'".$va_stat['last_vacuum']."'" : 'NULL');
	$lav=(isset($va_stat['last_autovacuum']) ? "'".$va_stat['last_autovacuum']."'" : 'NULL');
	$la=(isset($va_stat['last_analyze']) ? "'".$va_stat['last_analyze']."'" : 'NULL');
	$laa=(isset($va_stat['last_autoanalyze']) ? "'".$va_stat['last_autoanalyze']."'" : 'NULL');
	$this->sql->non_select_c("INSERT INTO table_va_stat VALUES ("
	.$this->id.","
	.$time_id.","
	.$lv.","
	.$lav.","
	.$la.","
	.$laa.")");

	$basic_stat_q="SELECT
pg_relation_size(oid) AS relsize,
pg_total_relation_size(oid) AS totalrelsize,
reltuples::bigint,
pg_stat_get_numscans(oid) AS seq_scan,
pg_stat_get_tuples_returned(oid) AS seq_tup_read,
pg_stat_get_tuples_fetched(oid) AS seq_tup_fetch,
pg_stat_get_tuples_inserted(oid) AS n_tup_ins,
pg_stat_get_tuples_updated(oid) AS n_tup_upd,
pg_stat_get_tuples_deleted(oid) AS n_tup_del,
pg_stat_get_tuples_hot_updated(oid) AS n_tup_hot_upd,
pg_stat_get_live_tuples(oid) AS n_live_tup,
pg_stat_get_dead_tuples(oid) AS n_dead_tup,
pg_stat_get_blocks_fetched(oid) AS heap_blks_fetch,
pg_stat_get_blocks_hit(oid) AS heap_blks_hit
FROM pg_class
WHERE oid=".$this->get_field('obj_oid');

	$prod_sql->select_c($basic_stat_q);
	$stat=$prod_sql->get_row_hash();

	$this->sql->non_select_c("INSERT INTO table_stat VALUES ("
	.$this->id.","
	.$time_id.","
	.$stat['relsize'].","
	.$stat['totalrelsize'].","
	.$stat['reltuples'].","
	.$stat['seq_scan'].","
	.$stat['seq_tup_read'].","
	.$stat['seq_tup_fetch'].","
	.$stat['n_tup_ins'].","
	.$stat['n_tup_upd'].","
	.$stat['n_tup_del'].","
	.$stat['n_tup_hot_upd'].","
	.$stat['n_live_tup'].","
	.$stat['n_dead_tup'].","
	.$stat['heap_blks_fetch'].","
	.$stat['heap_blks_hit'].")");

	if ($this->toast) {
	    $this->toast->get_stat($time_id,$prod_sql);
	}
	$this->initiate_composit('index_name',array('alive'=>'t'));
	foreach ($this->get_composit('index_name',COLLECTION_OBJECT_ARRAY) as $idx) {
	    $idx->get_stat($time_id,$prod_sql);
	}
    }




    public function __toString() {
	return $this->get_field('tbl_name');
    }
}

?>
